// @/utils/http.ts
import type { ResponseData } from "@/types/interface";
import { uniError } from "@/utils/MessageUtil";

// 配置 - 改为后端9010端口
const config = {
    baseURL: 'http://localhost:9010',
    timeout: 10000
}

type RequestConfig = {
    url: string;
    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'UPLOAD';
    data?: any;
    params?: any;
    header?: any;
}

class Http {
    private baseURL: string;
    private timeout: number;

    constructor(configs: typeof config) {
        this.baseURL = configs.baseURL;
        this.timeout = configs.timeout;
    }

    // 请求拦截器
    private requestInterceptor(config: RequestConfig) {
        // 处理token
        let token = "";
        // 实际项目中从存储中获取token
        // #ifdef MP-WEIXIN
        token = uni.getStorageSync('token') || '';
        // #endif
        // #ifdef H5
        token = localStorage.getItem('token') || '';
        // #endif

        if (token) {
            config.header = {
                ...config.header,
                'token': token
            };
        }
        return config;
    }

    // 响应拦截器
    private responseInterceptor(response: any) {
        if (response.statusCode === 200) {
            const responseData = response.data;
            if (responseData.code === 200) {
                return responseData;
            } else {
                const errMsg = responseData.msg || "业务处理失败";
                uniError(errMsg);
                return Promise.reject(new Error(errMsg));
            }
        } else {
            let errMsg = "";
            switch (response.statusCode) {
                case 400:
                    errMsg = "错误请求";
                    break;
                case 401:
                    errMsg = "未授权，请重新登录";
                    console.log("Token验证失败，需要重新登录");
                    // 清除本地存储的token和用户信息
                    // #ifdef MP-WEIXIN
                    uni.removeStorageSync('token');
                    uni.removeStorageSync('userInfo');
                    // #endif
                    // #ifdef H5
                    localStorage.removeItem('token');
                    localStorage.removeItem('userInfo');
                    // #endif
                    
                    // 跳转到登录页面
                    uni.reLaunch({
                        url: '/pages/login/login'
                    });
                    break;
                case 403:
                    errMsg = "拒绝访问";
                    break;
                case 404:
                    errMsg = "请求错误,未找到该接口";
                    break;
                case 408:
                    errMsg = "请求超时";
                    break;
                case 500:
                    errMsg = "后台接口出错";
                    break;
                case 504:
                    errMsg = "网络超时";
                    break;
                default:
                    errMsg = `未知错误(${response.statusCode})`;
                    break;
            }
            uniError(errMsg);
            return Promise.reject(new Error(errMsg));
        }
    }

    // 错误处理
    private handleError(error: any) {
        console.log('请求错误:', error);
        let errMsg = "连接到服务器失败";
        uniError(errMsg);
        return Promise.reject(new Error(errMsg));
    }

    // 核心请求方法
    private request<T = ResponseData<any>>(config: RequestConfig): Promise<T> {
        // 处理基础配置
        const url = this.baseURL + config.url;
        const header = {
            'Content-Type': 'application/json',
            ...config.header
        };

        // 请求拦截
        const requestConfig = this.requestInterceptor({
            ...config,
            url,
            header
        });

        console.log('发起请求:', requestConfig); // 添加调试日志

        return new Promise((resolve, reject) => {
            if (requestConfig.method === 'UPLOAD') {
                // 处理文件上传
                uni.uploadFile({
                    url: requestConfig.url,
                    filePath: requestConfig.data.filePath,
                    name: requestConfig.data.name || 'file',
                    formData: requestConfig.data.formData || {},
                    header: requestConfig.header,
                    timeout: this.timeout,
                    success: (response) => {
                        try {
                            // 解析响应数据
                            response.data = JSON.parse(response.data);
                            const result = this.responseInterceptor(response);
                            if (result instanceof Promise) {
                                result.then(resolve).catch(reject);
                            } else {
                                resolve(result as T);
                            }
                        } catch (e) {
                            reject(e);
                        }
                    },
                    fail: (error) => {
                        this.handleError(error).catch(reject);
                    }
                });
            } else {
                // 普通请求
                uni.request({
                    url: requestConfig.url,
                    method: requestConfig.method,
                    data: requestConfig.data,
                    params: requestConfig.params,
                    header: requestConfig.header,
                    timeout: this.timeout,
                    success: (response) => {
                        try {
                            const result = this.responseInterceptor(response);
                            if (result instanceof Promise) {
                                result.then(resolve).catch(reject);
                            } else {
                                resolve(result as T);
                            }
                        } catch (e) {
                            reject(e);
                        }
                    },
                    fail: (error) => {
                        this.handleError(error).catch(reject);
                    }
                });
            }
        });
    }

    // 新增：原生请求（不拼接任何baseURL，直接用完整URL）
    private rawRequest<T = any>(config: RequestConfig): Promise<T> {
        // 直接使用传入的url，不拼接baseURL
        const url = config.url;
        const header = {
            'Content-Type': 'application/json',
            ...config.header
        };

        // 请求拦截（但不处理URL拼接）
        const requestConfig = this.requestInterceptor({
            ...config,
            url,
            header
        });

        return new Promise((resolve, reject) => {
            // 构造 URL 参数
            let requestUrl = requestConfig.url;
            if (requestConfig.params) {
                const paramsStr = Object.keys(requestConfig.params)
                    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(requestConfig.params[key])}`)
                    .join('&');
                if (paramsStr) {
                    requestUrl += (requestUrl.includes('?') ? '&' : '?') + paramsStr;
                }
            }
            
            uni.request({
                url: requestUrl,
                method: requestConfig.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'TRACE' | 'CONNECT',
                data: requestConfig.data,
                header: requestConfig.header,
                timeout: this.timeout,
                success: (response) => {
                    try {
                        // 注意：高德地图的响应格式可能和你的后端不同，需要单独处理
                        if (response.statusCode === 200) {
                            resolve(response.data as T); // 直接返回高德的原始数据
                        } else {
                            uniError(`高德地图请求失败：${response.statusCode}`);
                            reject(new Error(`状态码：${response.statusCode}`));
                        }
                    } catch (e) {
                        reject(e);
                    }
                },
                fail: (error) => {
                    this.handleError(error).catch(reject);
                }
            });
        });
    }

    // 新增：供外部调用的原生get方法（专门用于第三方API）
    rawGet<T = any>(url: string, params?: object): Promise<T> {
        return this.rawRequest<T>({
            url,
            method: 'GET',
            params
        });
    }

    // post请求
    post<T = ResponseData<any>>(url: string, data?: object): Promise<T> {
        return this.request<T>({
            url,
            method: 'POST',
            data
        });
    }

    // delete请求
    delete<T = ResponseData<any>>(url: string): Promise<T> {
        return this.request<T>({
            url,
            method: 'DELETE'
        });
    }

    // put请求
    put<T = ResponseData<any>>(url: string, data?: object): Promise<T> {
        return this.request<T>({
            url,
            method: 'PUT',
            data
        });
    }

    // get请求
    get<T = ResponseData<any>>(url: string, params?: object): Promise<T> {
        return this.request<T>({
            url,
            method: 'GET',
            params
        });
    }

    // 图片上传
    upload<T = ResponseData<any>>(url: string, data: {
        filePath: string;
        name?: string;
        formData?: object;
    }): Promise<T> {
        return this.request<T>({
            url,
            method: 'UPLOAD',
            data
        });
    }
}

export default new Http(config);